/* Header file for sudoku solver
*
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

typedef unsigned int cell;
typedef cell* Grid;
typedef enum {FALSE, TRUE} bool;
typedef struct {
	int x;
	int y;
} cellCoord;

static __inline__ unsigned long long rdtsc(void)
{
  unsigned hi, lo;
  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

#define SUB_GRID_SIZE 3
#define GRID_SIZE (SUB_GRID_SIZE * SUB_GRID_SIZE)
#define gridIndex(g, x, y) *(g + GRID_SIZE*(y) + (x))
#define subGridIndex(g, sx, sy, x, y) *(g + GRID_SIZE * (SUB_GRID_SIZE * sy + y) + SUB_GRID_SIZE * sx + x)	//sx, sy are indexes for which subgrid. x, y are indexes within each subgrid
#define getSubGridX(x) (x/SUB_GRID_SIZE)	// Gets the index for which subgrid
#define getSubGridY(y) (y/SUB_GRID_SIZE)

/* 
*	Function declarations for grid_utils.c
*/
// Gets the number of bits that are 1
inline int bitCount (unsigned int u);

// clears the num bit
inline void clrCell (int num, cell * c);
// sets the num bit
inline void setCell (int num, cell * c);

bool unmarkCells (Grid g, int x, int y);
void prtCell (cell c, int type);
Grid newGrid (void);
void delGrid (Grid g);
void populateGrid (char * input, Grid g);
void prtGrid (Grid g, int type);
void prtGridBitcount(Grid g);
bool isGridSolved(Grid g);
cellCoord getLeastPossCell(Grid g);

bool unmarkCellsTuple (Grid g, int x, int y, cell tuple, int type);
 
// Algorithms
bool markup(Grid g);
bool determine(Grid gIn, Grid g);        		// 8 Functions added by Eshan
int onlyInColumn(Grid g, int x, int y);
int onlyInRow(Grid g, int x, int y);
int onlyInSquare(Grid g, int x, int y);
cell rowTuple(Grid g, int x, int y);
cell columnTuple(Grid g, int x, int y);
cell squareRowTuple(Grid g, int x, int y);
cell squareColumnTuple(Grid g, int x, int y);

// Backtrack
bool backtrack(Grid g, Grid gSolved);
